import z from 'zod';

/**
 * 创建结果模式
 *
 * 生成一个区分联合类型，用于验证成功和失败两种结果状态
 *
 * @template T - 成功时返回的数据类型
 * @param dataSchema - 成功时数据的Zod验证模式
 * @returns 包含成功和失败两种状态的结果模式
 */
export function result<T>(dataSchema: z.ZodType<T>) {
  return z
    .discriminatedUnion('success', [
      z.object({
        success: z.literal(true).describe('成功状态').meta({ example: true }),
        data: dataSchema,
      }),
      z.object({
        success: z.literal(false).describe('失败状态').meta({ example: false }),
        errKind: z.string().describe('错误类型').meta({ example: 'MayError' }),
        errMsg: z.string().describe('错误信息').meta({ example: '请求失败' }),
      }),
    ])
    .describe('Api 统一响应结果');
}

/**
 * 结果类型
 */
export type Result<T> = z.infer<ReturnType<typeof result<T>>>;

/**
 * 创建成功结果
 *
 * 返回一个表示操作成功的标准结果对象
 *
 * @template T - 返回数据的类型
 * @param data - 成功时返回的数据
 * @returns 包含成功状态和数据的结果对象
 */
export function ok<T>(data: T) {
  return {
    success: true as const,
    data,
  };
}

/**
 * 创建失败结果
 *
 * 返回一个表示操作失败的标准结果对象
 *
 * @param errKind - 错误类型，用于标识具体的错误类型
 * @param errMsg - 错误信息，描述失败的原因
 * @returns 包含失败状态、错误码和错误信息的结果对象
 */
export function fail(errKind: string, errMsg: string) {
  return {
    success: false as const,
    errKind,
    errMsg,
  };
}
